﻿using System.Collections.Generic;
using System.Linq;
using TechnicalIndicators.Points;
using Utils;

namespace TechnicalIndicators.DateBased
{
	public class Stochastic : GeneratorBase<DatedSeriePoint, DatedSeriePoint>
	{
		#region Attributes

		private int _period;
		private readonly List<decimal> _values;
		private int _valuesProcessed;

		private decimal _min;
		private decimal _max;

		#endregion

		#region Public Methods

		public Stochastic(ObservableCollection2<DatedSeriePoint> destination) : base(destination)
		{
			_values = new List<decimal>();
			_min = decimal.MaxValue;
			_max = decimal.MinValue;
		}

		public void Configure(int samples)
		{
			_period = samples;
		}
	
		protected override DatedSeriePoint CreatePoint(DatedSeriePoint point)
		{
			DatedSeriePoint newPoint = null;

			_valuesProcessed++;
			_values.Add(point.Y);

			if (point.Y < _min)
			{
				_min = point.Y;
			}

			if (point.Y > _max)
			{
				_max = point.Y;
			}

			if (_valuesProcessed >= _period)
			{
				if (_valuesProcessed > _period)
				{
					decimal firstValue = _values[0];
					_values.RemoveAt(0);

					if (firstValue == _min)
					{
						_min = _values.Min();
					}

					if (firstValue == _max)
					{
						_max = _values.Max();
					}
				}

				if (_max != _min)
				{
					newPoint = new DatedSeriePoint(point.X, 100 * (point.Y - _min) / (_max - _min));
				}
			}

			return newPoint;
		}

		public override void Clear()
		{
			_min = decimal.MaxValue;
			_max = decimal.MinValue;
			_values.Clear();
			_valuesProcessed = 0;
			base.Clear();
		}

		#endregion
	}
}
